package com.ruoyi.framework.aspectj;


import com.ruoyi.common.annotation.PrimaryKey;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Aspect
@Component
public class ParamCheckAspect {
    private static final Logger logger = LoggerFactory.getLogger(ParamCheckAspect.class);

    @Pointcut("@annotation(com.ruoyi.common.annotation.ParamCheck)")
    public void paramValidationPointcut() {
    }

//    @Before("paramValidationPointcut()")
//    public void before(JoinPoint point) {
//        this.logger.info(">>>>>ParamCheckAspect.before");
//
//        Map<String, StringBuffer> errorMap = new HashMap<String, StringBuffer>();
//        // 访问目标方法的参数名称parameterNames和方法method
//        MethodSignature methodSignature = (MethodSignature) point.getSignature();
//        String[] parameterNames = methodSignature.getParameterNames();
//        Method method = methodSignature.getMethod();
//        // 绑定参数
//        Map parameterMap = this.bindParameter(parameterNames, point.getArgs());
//        // 绑定注解类
//        Map<String, Class> clazzMap = null;
//        // 目标注解class
//        Class[] clazzs = null;
//        // 目标注解参数名称
//        List<String> parameters = null;
//
//        // 获取目标方法注解的类
//        if (method.isAnnotationPresent(ParamCheck.class)) {
//            clazzs = method.getAnnotation(ParamCheck.class).clazzs();
//            parameters = Arrays.asList(method.getAnnotation(ParamCheck.class).params());
//            clazzMap = this.bindClazz(parameters, clazzs);
//        }
//        AjaxResult result = AjaxResult.error();
//
//        // ParamCheck注解中的两个参数数量不能为空并且保持一致
//        if (clazzs.length > 0 && clazzs.length == parameters.size()) {
//            for (String parameter : parameterNames) {
//                if (parameters.contains(parameter)) {
//                    if (parameterMap.get(parameter) instanceof String) {
//                        // String 类型
//                        Object obj = JSONObject.parseObject((String) parameterMap.get(parameter), clazzMap.get(parameter));
//                        result = (AjaxResult) VerifyUtils.verify(obj, errorMap);
//                    } else {
//                        result = (AjaxResult) VerifyUtils.verify(parameterMap.get(parameter), errorMap);
//                    }
//                }
//            }
//        }
//
//        if (!result.isSuccess()) {
//            throw new IllegalArgumentException(result.MSG_TAG);
//        }
//    }

    @Before("paramValidationPointcut()")
    public void before(JoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            if (arg != null) {
                Field[] fields = arg.getClass().getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
                    if (field.isAnnotationPresent(PrimaryKey.class)) {
                        continue;
                    }
                    if (field.get(arg) == null || field.get(arg).equals("")) {
                        throw new IllegalArgumentException("参数校验失败：" + field.getName() + "不能为空");
                    }
                    /// ...
                }
            } else {
                throw new IllegalArgumentException("参数不能为空");
            }
        }
    }

    /**
     * 绑定参数
     *
     * @param parameterNames
     * @param args
     * @return
     */
    private Map<Object, Object> bindParameter(String[] parameterNames, Object[] args) {
        Map<Object, Object> map = new HashMap<>();
        for (int i = 0; i < parameterNames.length; i++) {
            map.put(parameterNames[i], args[i]);
        }
        return map;
    }

    private Map<String, Class> bindClazz(List<String> parameters, Class[] clazzs) {
        Map<String, Class> map = new HashMap<>();
        for (int i = 0; i < parameters.size(); i++) {
            map.put(parameters.get(i), clazzs[i]);
        }
        return map;
    }

}
